package com.bosssoft.platform.fasttcc.impl;

import com.bosssoft.platform.fasttcc.*;
import com.bosssoft.platform.fasttcc.log.file.FileTccLogger;
import com.bosssoft.platform.fasttcc.rpc.command.DefaultTccCommandHandler;
import com.bosssoft.platform.fasttcc.rpc.command.TccCommandHandler;
import com.bosssoft.platform.fasttcc.support.BeanClassFinder;
import com.bosssoft.platform.fasttcc.support.CompleteStageHelper;
import com.jfireframework.baseutil.StringUtil;

import javax.sql.DataSource;
import java.io.File;
import java.util.concurrent.ExecutorService;

public class DefaultTccConfiguration implements TccConfiguration
{
    private TccLogger             tccLogger;
    private TccOperationRegistry  registry;
    private String                logBaseDir;
    private BeanClassFinder       beanClassFinder;
    private XidFactory            xidFactory;
    private String                identifier;
    private ExecutorService       executorService;
    private CompleteStageHelper   completeStageHelper;
    private DataSource            dataSource;
    private TccCommandHandler     tccCommandHandler;
    private RemoteResourceFactory remoteResourceFactory;

    @Override
    public TccTransactionManager build()
    {
        if (logBaseDir == null)
        {
            logBaseDir = new File("").getAbsolutePath();
        }
        if (dataSource == null)
        {
            throw new IllegalArgumentException("尚未设置dataSource参数");
        }
        if (completeStageHelper == null)
        {
            throw new IllegalArgumentException("尚未设置completeStageHelper参数");
        }
        if (remoteResourceFactory == null)
        {
            throw new IllegalArgumentException("尚未设置RemoteHandlerClass参数");
        }
        if (tccLogger == null)
        {
            if (StringUtil.isNotBlank(logBaseDir) == false)
            {
                throw new IllegalArgumentException("尚未设置TccLogger,使用默认实现FileTccLogger，请设置logBaseDir参数");
            }
            tccLogger = new FileTccLogger(logBaseDir, dataSource);
        }
        if (registry == null)
        {
            if (beanClassFinder == null)
            {
                throw new IllegalArgumentException("尚未设置BeanClassFinder参数");
            }
            registry = new TccOperationRegistryImpl(beanClassFinder);
        }
        if (xidFactory == null)
        {
            xidFactory = new XidFactoryImpl();
        }
        if (tccCommandHandler == null)
        {
            tccCommandHandler = new DefaultTccCommandHandler();
        }
        TccTransactionManager manager;
        if (executorService == null)
        {
            manager = new TccTransactionManagerImpl(dataSource, xidFactory, tccLogger, identifier, remoteResourceFactory, registry, completeStageHelper, tccCommandHandler);
        }
        else
        {
            manager = new TccTransactionManagerImpl(dataSource, xidFactory, tccLogger, identifier, remoteResourceFactory, registry, completeStageHelper, tccCommandHandler, executorService);
        }
        return manager;
    }

    @Override
    public void setTccLogger(TccLogger tccLogger)
    {
        this.tccLogger = tccLogger;
    }

    @Override
    public void setTccOperationRegistry(TccOperationRegistry registry)
    {
        this.registry = registry;
    }

    @Override
    public void setBeanClassFinder(BeanClassFinder beanClassFinder)
    {
        this.beanClassFinder = beanClassFinder;
    }

    public void setLogBaseDir(String logBaseDir)
    {
        this.logBaseDir = logBaseDir;
    }

    @Override
    public void setXidFactory(XidFactory xidFactory)
    {
        this.xidFactory = xidFactory;
    }

    @Override
    public void setIdentifier(String identifier)
    {
        this.identifier = identifier;
    }

    @Override
    public void setRemoteResourceFactory(RemoteResourceFactory factory)
    {
        this.remoteResourceFactory = factory;
    }

    @Override
    public void setTccCommandHandler(TccCommandHandler tccCommandHandler)
    {
        this.tccCommandHandler = tccCommandHandler;
    }

    public void setExecutorService(ExecutorService executorService)
    {
        this.executorService = executorService;
    }

    @Override
    public void setCompleteStageHelper(CompleteStageHelper completeStageHelper)
    {
        this.completeStageHelper = completeStageHelper;
    }

    @Override
    public void setDataSource(DataSource dataSource)
    {
        this.dataSource = dataSource;
    }
}
